<script>
import axios from "axios";
// 用来显示markdown
import VueMarkdown from 'vue-markdown'
// 引入langchain调用ollama
import { Ollama } from "@langchain/community/llms/ollama";
import {getUserInfoFromToken} from "@/assets/js/TokenFunction";
export default {
  components: {
    VueMarkdown
  },
  data () {
    return {
      //输入的问题，提交的内容
      prompt: '',
      res: '',
      markdownContent: '# Hello **World**!',
      hydroData:'',
      /**
       * 双方的对话信息，结构为：
       * {type:bot或user,content:对话内容}
       * 并绑定在页面上实时显示
       */
      messages: [],
    }
  },
  mounted() {
    //获取水文数据
    this.getHydroData()
    //让AI说欢迎词
    // this.send("输出：‘你好，很高兴为您解答水利方面的问题’，其他多余的话别说")
    this.send("输出：‘你好，很高兴为您解答问题’，其他多余的话别说")
  },
  methods:{
    /**
     * 对话生成时，自动滚动到页面最底部
     */
     scrollToBottom() {
       this.$nextTick(() => {
         this.$refs.chatBox.scrollTop = this.$refs.chatBox.scrollHeight;
         console.log(this.$refs.chatBox.scrollTop)
       });
    },
    setHistory(userMsg,botMsg){

      axios.post("/hkgapi/chat/setChatHis",{
        userId:getUserInfoFromToken("userId"),
        userMsg:userMsg,
        botMsg:botMsg
      })
    },
    /**
     * 获取水文数据
     */
    getHydroData(){
      axios.post("/hkgapi/hydro/getAllRiverFromMysql").then(res=>{
        this.hydroData=res.data
      })
    },
    /**
     * 给ollama发送请求
     * @param question 你提的问题
     * @returns {Promise<void>}
     */
    async send(question) {
      //如果问题不是空的，才在messages里加入
      if(this.prompt!==''){
        this.messages.push({type:"user", content: this.prompt})
        this.scrollToBottom();
      //防止之后输入的时候，第一个空的会跳出来？我忘记为啥这么写了
      }else if(this.messages.length!==0){
        return
      }
      //建立请求
      //todo 上线改地址
      const ollama = new Ollama({
        baseUrl: "http://10.169.239.156:11434",
        // baseUrl: "http://localhost:11434",
        model: "qwen2:7b",
      });

      let chatArr=''
      async function  replayFnc() {
        const data = "请根据下列水文数据回答问题："+JSON.stringify(this.hydroData)+ "请自行判断问题是否和水利相关，不相关就回答'很抱歉，我将不会回答与水利无关的知识'。问题："+question
        // const data=question
        const response = await ollama.stream(data);//读取流
        this.messages.push({type:"bot", content: this.res})
        for await (const chunk of response) { //因为读下来的respone还是promise数据,所以还需要加await
         //此时拿到的chunk就是传输过来的一段段的字符或者字符串
          chatArr=chatArr+chunk//一点点传进去，就会动态显示在界面了
          setTimeout(() => {
            //拿到messages中的最后一个元素的content，更新他
            this.messages[this.messages.length-1].content=chatArr
            //滚动到底部
            this.scrollToBottom();
          }, 100);
        }

        if(this.prompt!==''){
          this.setHistory(question,chatArr)
        }
        //清空输入框
        this.prompt=''
        this.scrollToBottom(); // 发送后滚动到底部
      }

      // 执行消息流函数
      await replayFnc.call(this);
    },
  }

}
</script>

<template>
      <el-card  shadow="always">
          <div class="chat-box" ref="chatBox" >
            <div v-for="(msg, index) in messages" :key="index" class="message">
              <div class="message-container">
                <div v-if="msg.type === 'user'" class="user-message">
                  <div class="message-content user-message-content">{{ msg.content }}</div>
                </div>
              </div>
              <div v-if="msg.type === 'bot'" class="bot-message">
                <!--              <img :src="avatar_bot" alt="Bot" class="avatar" />-->
                <div class="message-content bot-message-content"> <vue-markdown :source="msg.content"></vue-markdown></div>
              </div>
            </div>
          </div>
        <!-- 输入框和按钮 -->
        <div class="input-area">
              <el-input @keydown.enter.native="send(prompt)"  class="input-field" :style="{ maxWidth: 'calc(100% - 100px)' }"  :rows="2" v-model="prompt"  placeholder="请输入问题"></el-input>
              <el-button type="success" icon="el-icon-s-promotion" style="margin-left: 10px" @click="send(prompt)">发送</el-button>

        </div>

      </el-card>

</template>

<style >
.chat-box {
  height: calc(100vh - 210px);
  overflow-y: auto;
  padding: 10px;
  border-bottom: 1px solid #dcdfe6;
}
.input-area {
  display: flex;
  align-items: center;
  margin-top: 10px;
}
.message {
  margin: 10px 0;
  display: flex;
  align-items: center;
}
.user-message, .bot-message {
  margin-top: 2px;
  display: flex;
  align-items: center;
}
.avatar {
  border-radius: 50%;
  margin-right: 10px;
  width: 50px;
  height: 50px;
}
.input-field {
  flex: 1;
  margin-right: 10px;
  max-width: calc(100% - 100px);
}
.message-content {
  max-width: 100%; /* 确保消息内容框不超过聊天框宽度 */
  background-color: #f0f0f0; /* 随意选择背景颜色 */
  border-radius: 5px; /* 圆角 */
  padding: 10px; /* 内边距 */
  overflow-wrap: break-word; /* 使长文本换行 */
  white-space: normal; /* 允许文本在标签内换行 */
  word-wrap: break-word; /* 兼容旧版浏览器 */
}
.user-message-content {
  background-color: #d1e7dd; /* 用户消息的背景颜色 */
}
.bot-message-content {
  background-color: #cfe2ff; /* 机器人消息的背景颜色 */
}

</style>